package action

import (
	"workspace/websocket/src/global"

	"strings"

	"encoding/json"

	"github.com/gorilla/websocket"
)

type Client struct {
	dispatcher *Dispatcher
	conn       *websocket.Conn //客户端连接
	sendData   chan []byte     //要发送给客户端的数据
	id         string          //客户端唯一标识
	time       int64           //客户端连接时间
	topics     []string        //订阅的产品代码
}

//发消息给客户端
func (this *Client) sendMessage() {
	defer func() {
		//消息发完后关闭连接
		this.conn.Close()
	}()

	//阻塞协程以免只能读取一次sendData通道内的数据就退出
	for {
		select {
		case data, ok := <-this.sendData: //从sendData通道中读取到数据时
			if !ok { //如果通道里没有了数据
				//发送关闭连接的消息给客户端
				this.conn.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}
			//发送数据给客户端
			this.conn.WriteMessage(websocket.TextMessage, data)
		}
	}
}

//从客户端读取数据
func (this *Client) readMessage() {
	//如果关闭了下面的for阻塞说明该客户端不存在了
	defer func() {
		//将客户端从池中删除
		this.dispatcher.removeClient <- this
		//关闭与该客户端的连接
		this.conn.Close()
	}()

	//阻塞协程以免只能读取一次客户端数据就退出函数，导致客户端被从池中删除
	for {
		//读取从客户端发来的数据
		_, message, err := this.conn.ReadMessage()
		if err != nil {
			this.dispatcher.removeClient <- this
			this.conn.Close()
			break
		}
		//如果客户端发来的数据不为空
		if len(message) > 0 {
			msg := string(message)
			global.Logger.Debug("客户端 " + this.id + " 消息：" + msg)
			//将客户端数据用JSON反序列成map
			jsonMap := make(map[string]string)
			err := json.Unmarshal(message, &jsonMap)
			if err != nil {
				global.Logger.Error(err.Error())
				continue
			}
			//判断客户端命令
			if jsonMap["cmd"] == "topics" {
				global.Logger.Debug("客户端 " + this.id + " 请求订阅 " + jsonMap["data"])
				//拆解出要订阅的产品代码
				this.topics = strings.Split(jsonMap["data"], ",")
				if err != nil {
					global.Logger.Warn(err.Error())
					continue
				}
			}
		}
	}
}
